内存管理是一个系统基本组成部分, FreeRTOS 中大量使用到了内存管理,比如创建任务、信号量、队列等会自动从堆中申请内存。用户应用层代码也可以 FreeRTOS 提供的内存管理函数来申请和释放内存,

  • 内存管理简介
  • 内存碎片
  • heap_1 内存分配方法
  • heap_2 内存分配方法
  • heap_3 内存分配方法
  • heap_4 内存分配方法
  • heap_5 内存分配方法

FreeRTOS 内存管理简介

FreeRTOS 创建任务、队列、信号量等的时候有两种方法,一种是动态的申请所需的 RAM。一种是由用户自行定义所需的 RAM,这种方法也叫静态方法,使用静态方法的函数一般以“ Static”结尾,比如任务创建函数 xTaskCreateStatic(),使用此函数创建任务的时候需要由用户定义任务堆栈,本章我们不讨论这种静态方法。使用动态内存管理的时候 FreeRTOS 内核在创建任务、队列、信号量的时候会动态的申请RAM。标准 C 库中的 malloc()和 free()也可以实现动态内存管理,但是如下原因限制了其使用:

  • 在小型的嵌入式系统中效率不高。
  • 会占用很多的代码空间。
  • 它们不是线程安全的。
  • 具有不确定性,每次执行的时间不同。
  • 会导致内存碎片。
  • 使链接器的配置变得复杂

不同的嵌入式系统对于内存分配和时间要求不同,因此一个内存分配算法可以作为系统的可选选项。 FreeRTOS 将内存分配作为移植层的一部分,这样 FreeRTOS 使用者就可以使用自己的合适的内存分配方法。

当内核需要 RAM 的时候可以使用 pvPortMalloc()来替代 malloc()申请内存,不使用内存的时候可以使用 vPortFree()函数来替代 free()函数释放内存。函数 pvPortMalloc()、 vPortFree()与函数 malloc()、 free()的函数原型类似。

FreeRTOS 提供了 5 种内存分配方法, FreeRTOS 使用者可以其中的某一个方法,或者自己的内存分配方法。这 5 种方法是 5 个文件,分别为:heap_1.c、 heap_2.c、 heap_3.c、 heap_4.c 和heap_5.c。这 5 个文件再 FreeRTOS 源码中,路径: FreeRTOS->Source->portable->MemMang。

内存碎片

看名字就知道是小块的、碎片化的内存。内存碎片是伴随着内存申请和释放而来的。

内存碎片是内存管理算法重点解决的一个问题,否则的话会导致实际可用的内存越来越少,最终应用程序因为分配不到合适的内存而奔溃! FreeRTOS 的 heap_4.c 就给我们提供了一个解决内存碎片的方法,那就是将内存碎片进行合并组成一个新的可用的大内存块。